package com.info.zhiduoduo.alipay.model.request;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.BankcardExtInfo;
import com.alipay.api.domain.Participant;
import com.info.zhiduoduo.alipay.constant.AlipayIdentityEnum;

import java.math.BigDecimal;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class TransferModel {

	/**  平台的订单编号 */
	private String orderNo;

	/** 转账金额, 单位元, 保留两位小数 */
	private BigDecimal transAmount;

	/** 订单名称 */
	private String orderTitle;

	/** 订单备注 */
	private String orderRemark;

	/*	*//**
	 * 付款方支付宝用户id，即签约方创客的支付宝用户id。用户签约的支付宝账号对应的支付宝唯一用户号。
	 * 以2088开头的16位纯数字组成。(只有签约成功时才会返回)
	 * <p> 不需要此字段
	 *//*
	private String signedAlipayUserId;*/

	/**
	 * 签约创客的企业支付宝资金记账本id
	 */
	private String accountBookId;

	/**
	 * 签约创客的支付宝平台签约号
	 */
	private String alipayAgreementNo;

	/** 收款方信息 */
	private PayeeInfo payeeInfo;

	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	@Accessors(chain = true)
	public static class PayeeInfo {

		/** 身份类型 1: ALIPAY_LOGON_ID 收款方支付宝登录号，支持邮箱和手机号格式 2: BANKCARD_NO银行卡 */
		private AlipayIdentityEnum identityEnum;

		/** 收款方是支付宝用户, 如果identityType = 1, 必传此字段 */
		private AlipayUser alipayUser;

		/** 收款方是银行卡, 如果identityType = 2, , 必传此字段 */
		private Bankcard bankcard;

		/** 收款方是资金记账本, 如果identityType = 3, , 必传此字段 */
		private AccountBook accountBook;

		public Participant toPayee() {
			Participant payee = new Participant();
			payee.setIdentityType(identityEnum.code);
			if (identityEnum == AlipayIdentityEnum.LOGON_ID) {
				payee.setIdentity(alipayUser.logonName);
				payee.setName(alipayUser.name);
			} else if (identityEnum == AlipayIdentityEnum.BANKCARD_ACCOUNT) {
				payee.setIdentity(bankcard.accountNo);
				payee.setName(bankcard.getName());
				BankcardExtInfo bankcardExtInfo = new BankcardExtInfo();
				bankcardExtInfo.setAccountType(bankcard.accountType);
				bankcardExtInfo.setInstName(bankcard.instName);
				bankcardExtInfo.setBankCode(bankcard.bankCode);
				bankcardExtInfo.setInstBranchName(bankcard.instBranchName);
				bankcardExtInfo.setInstProvince(bankcard.instProvince);
				bankcardExtInfo.setInstCity(bankcard.instCity);
				payee.setBankcardExtInfo(bankcardExtInfo);
			} else if (identityEnum == AlipayIdentityEnum.ACCOUNT_BOOK_ID) {
				payee.setIdentity(accountBook.getAccountBookId());
				JSONObject payeeExt = new JSONObject();
				payeeExt.put("agreement_no", accountBook.getAgreementNo());
				payeeExt.put("accountbook_scene_code", "SATF_FUND_BOOK");
				payee.setExtInfo(payeeExt.toJSONString());
			} else {
				// 暂时不支持直接转账到支付宝用户userid
			}
			return payee;
		}

		public static PayeeInfo of(AlipayIdentityEnum identityEnum, String identity, String name, String agreementNo) {
			PayeeInfo payeeInfo = new PayeeInfo();
			payeeInfo.setIdentityEnum(identityEnum);
			if (identityEnum == AlipayIdentityEnum.ACCOUNT_BOOK_ID) {
				payeeInfo.setAccountBook(new AccountBook(identity, agreementNo));
			} else if (identityEnum == AlipayIdentityEnum.LOGON_ID) {
				payeeInfo.setAlipayUser(new AlipayUser(identity, name));
			} else if (identityEnum == AlipayIdentityEnum.BANKCARD_ACCOUNT) {
				// 只支持个人银行阿卡
				Bankcard bankcard = new Bankcard().setAccountNo(identity).setAccountType("2").setName(name);
				// 银行卡信息
				payeeInfo.setBankcard(bankcard);
			}
			return payeeInfo;
		}

		/**
		 * 创建收款人为对公账户
		 *
		 * @param accountNo      银行卡号
		 * @param name           银行账户名, 个人银行卡的真实姓名或对公银行卡的公司账户名
		 * @param bankCode       收款对公账户的银行支行联行号，与instBranchName 二选一
		 * @param instBranchName 收款银行所属支行，与bankCode 二选一
		 * @return
		 */
		public static PayeeInfo ofPublicBankAcct(String accountNo, String name, String bankCode, String instName, String instBranchName) {
			PayeeInfo payeeInfo = new PayeeInfo();
			payeeInfo.setIdentityEnum(AlipayIdentityEnum.BANKCARD_ACCOUNT);
			// 对公账户
			Bankcard bankcard = new Bankcard().setAccountNo(accountNo)
					.setAccountType("1")
					.setName(name)
					.setBankCode(bankCode)
					.setInstName(instName)
					.setInstBranchName(instBranchName);
			// 银行卡信息
			payeeInfo.setBankcard(bankcard);
			return payeeInfo;
		}
	}

	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	@Accessors(chain = true)
	public static class AccountBook {

		/** 记账本id account_book_id */
		private String accountBookId;

		/** agreement_no 子户开通协议号。 */
		private String agreementNo;
	}

	/**
	 * 支付宝用户信息
	 */
	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	@Accessors(chain = true)
	public static class AlipayUser {

		/** 支付宝用户的登录名, 邮箱或者手机号 */
		private String logonName;

		/** 支付宝实名认证的真实姓名 */
		private String name;
	}

	/**
	 * 如果identity_type为BANKCARD_NO需传递该参数，涉及属性如下：
	 * inst_name 银行卡卡开户银行
	 * inst_province 银行所在省份
	 * inst_city 银行所在市
	 * inst_branch_name 收款银行所属支行
	 * bank_code 银行卡支行联行号
	 * account_type 银行卡账户类型 1:对公 2：对私
	 */
	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	@Accessors(chain = true)
	public static class Bankcard {

		/**
		 * 银行卡号
		 */
		private String accountNo;

		/**
		 * 银行账户名, 个人银行卡的真实姓名或对公银行卡的公司账户名
		 */
		private String name;

		/**
		 * 收款账户类型。
		 * 1：对公（在金融机构开设的公司账户）,如果银行卡为对公，必须传递省市支行信息或者联行号
		 * 2：对私（在金融机构开设的个人账户）
		 */
		private String accountType;

		/**
		 * 银行支行联行号
		 */
		private String bankCode;

		/**
		 * 收款银行所属支行
		 */
		private String instBranchName;

		/**
		 * 收款银行所在市
		 */
		private String instCity;

		/**
		 * 机构名称
		 */
		private String instName;

		/**
		 * 银行所在省份
		 */
		private String instProvince;
	}

}
